/**
 * @description: 柯里化
 * @param {*} func
 * @param {array} args1
 * @return {*}
 */
export function curry(func, ...args1) {
  if (typeof func !== 'function') {
    throw new TypeError('The first argument must be a function');
  }
  return function curried(...args2) {
    const totalArgs = [...args1, ...args2];
    if (totalArgs.length >= func.length) {
      return func(...totalArgs);
    } else {
      return curry(func, ...totalArgs);
    }
  }
}
/**
 * @description: 生成图片导入路径
 * @param {*} basePath
 * @param {*} imageName
 * @return {*}
 */
function generateImagePath(basePath, imageName) {
  return `/src/assets/${basePath}/${imageName}`;
}
/**
 * @description: 导入Home文件夹的资源
 * @return {*}
 */
export const impHome = curry(generateImagePath, 'home');

/**
 * @description: 生成id
 * @return {*}
 */
export const uniqueId = (() => {
  let _id = 1
  return (prefix) => prefix ? prefix + (_id++) : _id++
})()

/**
 * @description: 深度判断结构是否相同
 * @param {*} obj1
 * @param {*} obj2
 * @param {*} seen
 * @return {*}
 */
export function deepEqual(obj1, obj2, visited = new WeakSet()) {
  // 处理循环引用
  if (typeof obj1 === 'object' && obj1 !== null) {
      if (visited.has(obj1)) return true;
      visited.add(obj1);
  }

  // 类型不同直接返回 false
  if (typeof obj1 !== typeof obj2) return false;

  // 处理基本类型（含 NaN）
  if (obj1 === obj2) return true;
  if (Number.isNaN(obj1) && Number.isNaN(obj2)) return true;

  // 处理 null
  if (obj1 === null || obj2 === null) return obj1 === obj2;

  // 处理数组
  if (Array.isArray(obj1)) {
      if (!Array.isArray(obj2) || obj1.length !== obj2.length) return false;
      return obj1.every((item, index) => deepEqual(item, obj2[index], visited));
  }

  // 处理 Date 对象
  if (obj1 instanceof Date && obj2 instanceof Date) {
      return obj1.getTime() === obj2.getTime();
  }

  // 处理 RegExp 对象
  if (obj1 instanceof RegExp && obj2 instanceof RegExp) {
      return obj1.toString() === obj2.toString();
  }

  // 处理 Map 对象
  if (obj1 instanceof Map && obj2 instanceof Map) {
      if (obj1.size !== obj2.size) return false;
      for (const [key, value] of obj1.entries()) {
          if (!obj2.has(key) || !deepEqual(value, obj2.get(key), visited)) {
              return false;
          }
      }
      return true;
  }

  // 处理 Set 对象
  if (obj1 instanceof Set && obj2 instanceof Set) {
      if (obj1.size !== obj2.size) return false;
      return [...obj1].every((item) => obj2.has(item));
  }

  // 处理普通对象
  if (typeof obj1 === 'object') {
      const keys1 = Object.keys(obj1);
      const keys2 = Object.keys(obj2);

      if (keys1.length !== keys2.length) return false;
      if (!keys1.every(k => keys2.includes(k))) return false;

      return keys1.every(key => deepEqual(obj1[key], obj2[key], visited));
  }

  return false;
}

/**
 * @description: 按照模板对象的结构，比对旧的对象，如果模板对象新增属性，旧的对象也新增，都存在的不变，多的删除
 * @param {*} template
 * @param {*} oldObject
 * @param {*} needDelete
 * @return {*}
 */
export function deepCompareUpdate(template, oldObject, { needDelete = true } = {}) {
  // 处理模板对象是数组的情况
  if (Array.isArray(template)) {
    if (!Array.isArray(oldObject)) {
      // eslint-disable-next-line no-param-reassign
      oldObject = [];
    }
    // 处理数组元素
    const newArray = [];
    for (let i = 0; i < template.length; i++) {
      if (oldObject[i]) {
        newArray[i] = deepCompareUpdate(template[i], oldObject[i]);
      } else {
        newArray[i] = cloneDeep(template[i]);
      }
    }
    return newArray;
  }

  // 处理模板对象是普通对象的情况
  if (typeof template === 'object' && template !== null) {
    const newObject = {};
    for (const key in template) {
      if (oldObject && key in oldObject) {
        // 如果有，递归处理，深度比较
        newObject[key] = deepCompareUpdate(template[key], oldObject[key]);
      } else {
        // 没有，直接赋值(深拷贝)
        newObject[key] = cloneDeep(template[key]);
      }
    }
    // 删除旧对象中不在模板中的属性
    if (needDelete) {
      if (oldObject) {
        for (const key in oldObject) {
          if (!template.hasOwnProperty(key)) {
            delete oldObject[key];
          }
        }
      }
    }
    // 合并新旧对象，新的属性新增，旧的属性删除
    return { ...oldObject, ...newObject };
  }

  // 处理基本类型，直接返回旧的
  return oldObject;
}

/**
 * @description: 判断类型
 * @param {*} type
 * @return {*}
 */
export function isType(type) {
  return function (target) {
    if (target[Symbol.toStringTag] !== undefined) {
      throw new Error('[Symbol.toStringTag] property is set')
    }
    return Object.prototype.toString.call(target) === `[object ${type}]`
  }
}